package in.co.codedoc.user;

import java.util.ArrayList;
import java.util.Iterator;

import in.co.codedoc.cg.annotations.HasProperties;
import in.co.codedoc.cg.annotations.IsMappedToJSON;
import in.co.codedoc.cg.annotations.Property;
import in.co.codedoc.encode.URIEncoding;
import in.co.codedoc.encrypt.Signer;
import in.co.codedoc.json.JSONUtil;
import in.co.codedoc.sql.SessionLocal;

@IsMappedToJSON
@HasProperties
({
	@Property(name="id",datatypeName="in.co.codedoc.user.UserId"),
	@Property(name="name",datatype=String.class),
	@Property(name="roles",datatype=String[].class)
})
public class Authorization
	extends AuthorizationBase
{

	public static Authorization SetCurrentAuthorization(Authorization auth)
	{
		currentAuthorization.set(auth);
		
		return auth;
	}

	public static Authorization GetCurrentAuthorization()
	{
		return currentAuthorization.get();
	}
	
	private static SessionLocal<Authorization> currentAuthorization
		= new SessionLocal<Authorization>();

	public static Authorization SetCurrentAuthorization(User user)
	{
		return SetCurrentAuthorization(MakeAuthorization(user));
	}
	
	public String MakeAuthorizationCookieData(long lifespan)
	{
		StringBuffer cookieData = new StringBuffer();
		
		cookieData.append
			(
				JSONUtil.Encode
				(
					this,
					Authorization.class.getCanonicalName()
				).Encode()
			);
	
		long validUntil = System.currentTimeMillis() + (lifespan * 1000);
	
		cookieData.append('-').append(validUntil);	
	
		String signature = Signer.Sign(cookieData.toString().getBytes(),validUntil);
	
		cookieData.append('-').append(signature);
		
		return URIEncoding.Encode(cookieData.toString());
	}
	
	@SuppressWarnings("unchecked")
	public static Authorization MakeAuthorization(User user)
	{
		Iterator<Long> iter = user.GetRoleSetId().Get().iterator();
		
		ArrayList<String> roleNames = new ArrayList<String>();
		while(iter.hasNext())
		{
			Role role = Role.FindById(RoleId.Create(iter.next()));
			if(role != null)
			{
				roleNames.add(role.GetName());
			}
		}
		
		Authorization auth = new Authorization();
		auth.SetId(user.GetId());
		auth.SetName(user.GetName());
		auth.SetRoles(roleNames.toArray(new String[roleNames.size()]));
		
		return auth;
	}
}
